package net.pimpas.web.jsf.renderers.accordionpanel.html;

import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

import net.pimpas.web.jsf.components.accordionpanel.UIAccordionPanel;
import net.pimpas.web.jsf.components.div.UIDiv;
import net.pimpas.web.jsf.components.graphicimage.UIGraphicImage;
import net.pimpas.web.jsf.components.span.UISpan;
import net.pimpas.web.jsf.renderers.RendererBase;
import net.pimpas.web.jsf.util.ComponentUtils;

import org.apache.myfaces.shared_impl.renderkit.html.HTML;

public class HtmlAccordionPanelRenderer extends RendererBase {
	
	@SuppressWarnings("unchecked")
	@Override
	public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
		if(!component.isRendered()) return;
		if(!ComponentUtils.isCorrectComponentType(component, UIAccordionPanel.class)) return;
		
		super.initResourceManager(context, component);
		
		UIAccordionPanel panel = (UIAccordionPanel) component;
		this.processImports(context, panel);
		// create main span
		
		component.getAttributes().put("mainSpan", ((UISpan) context.getApplication().createComponent(UISpan.COMPONENT_TYPE)));
		UISpan mainSpan = (UISpan) component.getAttributes().get("mainSpan");
		mainSpan.setId(component.getId());
		
		// create span accordionPanel
		component.getAttributes().put("accordSpan", (UISpan) context.getApplication().createComponent(UISpan.COMPONENT_TYPE));
		UISpan accordSpan = (UISpan) component.getAttributes().get("accordSpan");
		accordSpan.setStyleClass("accordPanel");
		accordSpan.setId(component.getId()+"_accordPanel");
		
		Renderer spanRenderer = context.getRenderKit().getRenderer(UISpan.COMPONENT_FAMILY, UISpan.COMPONENT_RENDER_TYPE); 
		
		spanRenderer.encodeBegin(context, mainSpan);
		
		spanRenderer.encodeBegin(context, accordSpan);
		// encode title
		this.encodeTitle(context, panel);
		
		UIDiv content = (UIDiv) context.getApplication().createComponent(UIDiv.COMPONENT_TYPE);
		content.setStyleClass("accordPanelContent");
		content.setNoId(Boolean.FALSE);
		content.setId(component.getId()+UIAccordionPanel.CONTENT_ID);
		component.getAttributes().put(UIAccordionPanel.CONTENT_ID, content.getClientId(context));
		component.getAttributes().put(UIAccordionPanel.COMPONENT_CONTENT, content);
		
		Renderer divRenderer = context.getRenderKit().getRenderer(UIDiv.COMPONENT_FAMILY, UIDiv.COMPONENT_RENDER_TYPE);
		
		divRenderer.encodeBegin(context, content);
	}

	private void processImports(FacesContext context, UIAccordionPanel panel) {
		
		if(panel.getComponentPath().equals(UIAccordionPanel.DEFAULT_COMPONENT_PATH)) {
			this.getResourceManager().addJavascriptHeader(
					"js/"+UIAccordionPanel.DEFAULT_JS);
			this.getResourceManager().addStylesheetHeader(
					"css/"+UIAccordionPanel.DEFAULT_CSS);
		} else {
			this.getResourceManager().addJavascriptHere(panel.getComponentPath()+
					"js/"+UIAccordionPanel.DEFAULT_JS);
			this.getResourceManager().addStylesheetHere(panel.getComponentPath()+
					"css/"+UIAccordionPanel.DEFAULT_CSS);
		}
	}

	@SuppressWarnings("unchecked")
	private void encodeTitle(FacesContext context, UIAccordionPanel panel) throws IOException {
		// write table
		ResponseWriter writer = context.getResponseWriter();
		writer.startElement(HTML.TABLE_ELEM, panel);
		writer.writeAttribute(HTML.CLASS_ATTR, "accordPanelTitle", null);
		
		// first tr
		writer.startElement(HTML.TR_ELEM, panel);
		
		// first td
		writer.startElement(HTML.TD_ELEM, panel);
		writer.writeAttribute(HTML.CLASS_ATTR, "firstColumnIcon", null);
		
		// write icon
		UISpan icon = (UISpan) context.getApplication().createComponent(UISpan.COMPONENT_TYPE);
		icon.setStyleClass("accordPanelTitleIcon");
		icon.setNoId(Boolean.TRUE);
		
		// image
		String imageSrc = panel.getIcon();
		UIGraphicImage image = (UIGraphicImage) context.getApplication().createComponent(UIGraphicImage.COMPONENT_TYPE);
		if(panel.getComponentPath().equals(UIAccordionPanel.DEFAULT_COMPONENT_PATH))
			imageSrc = this.getResourceManager().getResourceUri("images/"+imageSrc);
		else
			imageSrc = panel.getComponentPath()+"images/"+imageSrc;
			
		image.setUrl(imageSrc);
		image.setStyleClass("icon");
		icon.getChildren().add(image);
		
		Renderer spanRenderer = context.getRenderKit().getRenderer(UISpan.COMPONENT_FAMILY, UISpan.COMPONENT_RENDER_TYPE);
		
		spanRenderer.encodeBegin(context, icon);
		spanRenderer.encodeChildren(context, icon);
		spanRenderer.encodeEnd(context, icon);
		
		// close td
		writer.endElement(HTML.TD_ELEM);
		
		// second td
		writer.startElement(HTML.TD_ELEM, panel);
		writer.writeAttribute(HTML.CLASS_ATTR, "secondColumnText", null);
		
		UISpan titleTextSpan = (UISpan) context.getApplication().createComponent(UISpan.COMPONENT_TYPE);
		titleTextSpan.setStyleClass("text");
		titleTextSpan.setNoId(Boolean.TRUE);
		
		UIOutput titleText = (UIOutput) context.getApplication().createComponent(UIOutput.COMPONENT_TYPE);
		titleText.setValue(panel.getTitle());
		titleTextSpan.getChildren().add(titleText);
		
		spanRenderer.encodeBegin(context, titleTextSpan);
		spanRenderer.encodeChildren(context, titleTextSpan);
		spanRenderer.encodeEnd(context, titleTextSpan);
		
		// close td
		writer.endElement(HTML.TD_ELEM);
		
		// third td
		writer.startElement(HTML.TD_ELEM, panel);
		writer.writeAttribute(HTML.CLASS_ATTR, "thirdColumnDropdown", null);
		
		UISpan dropdownSpan = (UISpan) context.getApplication().createComponent(UISpan.COMPONENT_TYPE);
		dropdownSpan.setStyleClass("accordPanelTitleDropDown");
		dropdownSpan.setNoId(Boolean.TRUE);
		UIGraphicImage dropdownImage = (UIGraphicImage) context.getApplication().createComponent(UIGraphicImage.COMPONENT_TYPE);
		
		String imageName = (panel.getState().equals(UIAccordionPanel.COLAPSED_STATE) ? 
				UIAccordionPanel.DEFAULT_DROPDOWN_DOWN : 
					UIAccordionPanel.DEFAULT_DROPDOWN_UP);
		if(panel.getComponentPath().equals(UIAccordionPanel.DEFAULT_COMPONENT_PATH))
			imageName = this.getResourceManager().getResourceUri("images/"+imageName);
		else
			imageName = panel.getComponentPath()+"images/"+imageName;
		
		dropdownImage.setUrl(imageName);
		dropdownImage.setStyleClass("dropdown");
		dropdownSpan.getChildren().add(dropdownImage);
		
		spanRenderer.encodeBegin(context, dropdownSpan);
		spanRenderer.encodeChildren(context, dropdownSpan);
		spanRenderer.encodeEnd(context, dropdownSpan);
		
		// close td
		writer.endElement(HTML.TD_ELEM);
		
		// end tr
		writer.endElement(HTML.TR_ELEM);
		
		// close table
		writer.endElement(HTML.TABLE_ELEM);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
		
		// div text
		UIDiv textContentDiv = (UIDiv) context.getApplication().createComponent(UIDiv.COMPONENT_TYPE);
		textContentDiv.setStyleClass("text");
		textContentDiv.setNoId(Boolean.TRUE);
		
		Renderer divRenderer = context.getRenderKit().getRenderer(UIDiv.COMPONENT_FAMILY, UIDiv.COMPONENT_RENDER_TYPE);
		
		
		divRenderer.encodeBegin(context, textContentDiv);
		
		super.encodeChildren(context, component);
		
		divRenderer.encodeEnd(context, textContentDiv);
		UIDiv content = (UIDiv) component.getAttributes().remove(UIAccordionPanel.COMPONENT_CONTENT);
		if(content != null) {
			divRenderer.encodeEnd(context, content);
			component.getAttributes().put(UIAccordionPanel.CONTENT_ID, content.getClientId(context));
		}
	}
	
	@Override
	public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
		if(!component.isRendered()) return;
		if(!ComponentUtils.isCorrectComponentType(component, UIAccordionPanel.class)) return;
		
		Renderer spanRenderer = context.getRenderKit().getRenderer(UISpan.COMPONENT_FAMILY, UISpan.COMPONENT_RENDER_TYPE);
		
		UISpan accordSpan = (UISpan) component.getAttributes().get("accordSpan");
		UISpan mainSpan = (UISpan) component.getAttributes().get("mainSpan");
		
		if(accordSpan != null && mainSpan != null) {
		
			component.getAttributes().remove("accordSpan");
			component.getAttributes().remove("mainSpan");
			
			spanRenderer.encodeEnd(context, accordSpan);
			spanRenderer.encodeEnd(context, mainSpan);
			
			this.initJavascript( context, (UIAccordionPanel) component, accordSpan.getClientId(context) );
		}
	}

	private void initJavascript(FacesContext context, UIAccordionPanel panel, String accordId) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
		writer.startElement(HTML.SCRIPT_ELEM, panel);
		writer.writeText("initAccordPanel('"+accordId+"', "+this.getIntegerState(panel)+")", null);
		writer.endElement(HTML.SCRIPT_ELEM);
	}
	
	private int getIntegerState(UIAccordionPanel panel) {
		return (panel.getState().equals(UIAccordionPanel.EXPANDED_STATE)) ? 0 : 1;
	}
}